package com.shigu.mo.services;

import com.opentae.core.mybatis.utils.FieldUtil;
import com.opentae.data.mall.beans.*;
import com.opentae.data.mall.examples.*;
import com.opentae.data.mall.interfaces.*;
import com.shigu.admin.manager.utils.BeanMapper;
import com.shigu.agent.exceptions.AgentException;
import com.shigu.agent.exceptions.YeepayException;
import com.shigu.agent.processes.AgentProcess;
import com.shigu.component.shiro.CustomCredentialsMatcher;
import com.shigu.main4.common.util.MoneyUtil;
import com.shigu.main4.common.util.SecretUtil;
import com.shigu.mo.bo.PayedCallbackBO;
import com.shigu.mo.bo.SettlementCallbackBO;
import com.shigu.mo.enums.SessionEnum;
import com.shigu.mo.exceptions.MoException;
import com.shigu.mo.utils.CardOcrUtil;
import com.shigu.mo.utils.LinknoUtil;
import com.shigu.mo.vo.*;
import com.shigu.passageway.Passageway;
import com.shigu.passageway.bo.RegistBO;
import com.shigu.passageway.exceptions.PassagewayException;
import com.shigu.passageway.exceptions.UnpayException;
import com.shigu.route.PassagewayRoute;
import com.shigu.route.bo.WaySelBO;
import com.shigu.wx.web.WxTempleateBaseData;
import com.shigu.wx.web.services.WxTokenService;
import com.unpay.skb.requests.ConsumptionRequest;
import com.unpay.skb.responses.ConsumptionResponse;
import com.yeepay.skb.biz.ReceviePartsBuiler;
import com.yeepay.skb.biz.WithdrawBuilder;
import com.yeepay.skb.results.ReceviePartsResult;
import com.yeepay.skb.results.WithdrawResult;
import com.yeepay.skb.util.AESUtil;
import com.yeepay.skb.util.Conts;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpSession;
import java.beans.IntrospectionException;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 商户的操作
 */
@Service
public class BusinessService {

    private static final Logger logger = LoggerFactory.getLogger(BusinessService.class);

    @Value("${system.rate}")
    private Double systemRate;

    @Value("${main_host}")
    private String MAIN_HOST;

    @Value("${wx.template.newcom}")
    private String NEW_COM;

    @Value("${me.flag}")
    private String OEM_FLAG;

    @Value("${wx.template.payed}")
    private String PAYED_TEMPLATE;

    @Value("${wx.notify.admin}")
    private String ADMIN_NOTIFY;

    @Autowired
    MoCardMapper moCardMapper;

    @Autowired
    CardOcrUtil cardOcrUtil;

    @Autowired
    LinknoUtil linknoUtil;

    @Autowired
    MoPassagewayAccountMapper moPassagewayAccountMapper;

    @Autowired
    private MoBankLimitMapper moBankLimitMapper;

    @Autowired
    MoProvMapper moProvMapper;

    @Autowired
    MoUserNormalProvMapper moUserNormalProvMapper;

    @Autowired
    MoCityMapper moCityMapper;

    @Autowired
    MoTownMapper moTownMapper;

    @Autowired
    ManagerUserMapper managerUserMapper;

    @Autowired
    MoOrderMapper moOrderMapper;

    @Autowired
    MoSettlementMapper moSettlementMapper;

    @Autowired
    MoShareProfitMapper moShareProfitMapper;

    @Autowired
    MoWxuserinfoMapper moWxuserinfoMapper;

    @Autowired
    AgentProcess agentProcess;

    @Autowired
    MoBankMapper moBankMapper;

    @Autowired
    WxTokenService wxTokenService;

    @Autowired
    PassagewayRoute passagewayRoute;

    @Autowired
    MoPassagewayMapper moPassagewayMapper;



    /**
     * 翻譯fromid成userId
     * @param fromId
     * @return
     */
    public Long parseRegeditFromId(String fromId,HttpSession session){
        if (StringUtils.isEmpty(fromId)||!fromId.startsWith("from")) {//如果没有，取一下session里面
            fromId= (String) session.getAttribute(SessionEnum.FROM_SPREADWAY.toString());
            if (StringUtils.isEmpty(fromId)) {
                return null;
            }
        }
        try {
            return Long.valueOf(fromId.replace("from",""));
        } catch (NumberFormatException e) {
            return null;
        }
    }

    /**
     * 查储蓄卡
     * @param userId
     * @return
     * @throws MoException
     */
    public CardVO selMyCashCard(Long userId) throws MoException {
        ManagerUser user=managerUserMapper.selectByPrimaryKey(userId);
        if (!user.getHasRealName()) {
            throw new MoException("还未实名认证");
        }
        CardVO cardVO=new CardVO();
        cardVO.setRealName(user.getRealName());
        cardVO.setBlank(user.getBankName());
        cardVO.setCardNo(user.getBankNumber());
        cardVO.setCardId(userId);
        cardVO.setBodyNumber(user.getIdCard());
        return cardVO;
    }

    /**
     * 获取用户最后一次使用的信用卡
     * @param userId 用户ID
     * @return
     */
    public CardVO selLastUsedCard(Long userId){
        MoCardExample example=new MoCardExample();
        example.createCriteria().andUserIdEqualTo(userId);
        example.setStartIndex(0);
        example.setEndIndex(1);
        example.setOrderByClause("last_use desc");
        List<MoCard> cards=moCardMapper.selectByConditionList(example);
        if (cards.size()>0) {
            return parseCardVO(cards.get(0));
        }
        return null;
    }

    /**
     * 查询我的刷卡费率
     * @param userId
     * @return
     */
    public String selMyRate(Long userId){
        MoPassagewayAccountExample example=new MoPassagewayAccountExample();
        example.createCriteria().andUserIdEqualTo(userId);
        example.setStartIndex(0);
        example.setEndIndex(1);
        List<MoPassagewayAccount> rates=moPassagewayAccountMapper.selectByConditionList(example);
        if (rates.size()>0) {
            Double rate=Double.valueOf(rates.get(0).getRate())*100;
            DecimalFormat df=new DecimalFormat("0.00");
            return df.format(rate)+"%";
        }
        return "0.50%";
    }

    /**
     * card的格式转化
     * @param mc
     * @return
     */
    private CardVO parseCardVO(MoCard mc){
        CardVO card=new CardVO();
        card.setCardId(mc.getCardId());
        card.setCardNo(mc.getBankNo());
        card.setBlank(mc.getBankName());
        card.setRealName(mc.getBankUser());
        return card;
    }

    /**
     * 设置常用银行卡
     * @param userId
     * @param cardId
     */
    public void setUsedCard(Long userId,Long cardId){
        MoCardExample example=new MoCardExample();
        example.createCriteria().andUserIdEqualTo(userId).andLastUseEqualTo(true);
        MoCard card=new MoCard();
        card.setLastUse(false);
        moCardMapper.updateByExampleSelective(card,example);//先把所有设置成不常用
        card.setCardId(cardId);
        card.setLastUse(true);
        moCardMapper.updateByPrimaryKeySelective(card);//再把当前设置成常用
    }

    @Transactional(rollbackFor = Exception.class)
    public void addCreditCard(Long userId,String creditCard,String bankName) throws MoException {
        MoBankExample bkexample=new MoBankExample();
        bkexample.createCriteria().andBankNameEqualTo(bankName);
        List<MoBank> myBanks=moBankMapper.selectByExample(bkexample);
        if (myBanks.size()==0) {
            throw new MoException(bankName+",此开户行不存在");
        }
        MoBank bank=myBanks.get(0);
        //先把所有使用过的设置为false
        MoCard card=new MoCard();
        card.setLastUse(false);
        MoCardExample example=new MoCardExample();
        example.createCriteria().andUserIdEqualTo(userId);
        moCardMapper.updateByExampleSelective(card,example);
        //放入新卡
        card=new MoCard();
        card.setLastUse(true);
        card.setBankNo(creditCard);
        card.setBankUser("");
        card.setBankLocation("");
        card.setBankName(bankName);
        card.setUserId(userId);
        card.setBankIcon(bank.getImgIcon());
        try {
            moCardMapper.insertSelective(card);
        } catch (Exception e) {
            throw new MoException("不能重复添加");
        }
    }

    /**
     * OCR完银行图片，并保存
     * @param userId
     * @param imgbase64
     * @return
     * @throws MoException
     */
    public String postCashImg(Long userId,String imgbase64) throws MoException {
        CardOCR card=cardOcrUtil.blankCard(imgbase64,userId);
        String imgUrl=card.getImgUrl();
        ManagerUser user=new ManagerUser();
        user.setUserId(userId);
        user.setBankCardUrl(imgUrl);
        managerUserMapper.updateByPrimaryKeySelective(user);
        return card.getCardNum();
    }

    /**
     * OCR完身份证，并保存
     * @param userId
     * @param imgbase64
     * @return
     * @throws MoException
     */
    public BodyIDOCR postIDCard(Long userId,String imgbase64) throws MoException {
        BodyIDOCR bodyIDOCR=cardOcrUtil.bodayIDCard(userId,imgbase64);
        String imgUrl=bodyIDOCR.getImgUrl();
        ManagerUser user=new ManagerUser();
        user.setUserId(userId);
        user.setIdCardUrl(imgUrl);
        user.setRealName(bodyIDOCR.getName());
        managerUserMapper.updateByPrimaryKeySelective(user);
        return bodyIDOCR;
    }

    /**
     * 得到银行卡列表
     * @param bankType 1针对结算，2针对信用卡
     * @return
     */
    @Cacheable(value = "bankdata_cach",key = "#bankType+'_'+#keyword")
    public List<BankVO> selBankList(int bankType,String keyword){
        MoBankExample example=new MoBankExample();
        MoBankExample.Criteria cri=example.createCriteria().andUseForEqualTo(bankType);
        if (StringUtils.isNotEmpty(keyword)) {
            cri.andBankNameLike("%"+keyword+"%");
        }
        return moBankMapper.selectByExample(example).stream().map(o->{
            BankVO vo=new BankVO();
            vo.setBankName(o.getBankName());
            vo.setBankIcon(o.getImgIcon());
            return vo;
        }).collect(Collectors.toList());
    }

    /**
     * 常用省
     * @param userId
     * @return
     */
    public List<ProvVO> selCommonlyProv(Long userId){
        MoUserNormalProvExample example=new MoUserNormalProvExample();
        example.createCriteria().andUserIdEqualTo(userId);
        example.setOrderByClause("use_time desc");
        return parseProv(BeanMapper.mapList(moUserNormalProvMapper.selectByExample(example),MoProv.class));
    }

    /**
     * 查省数据
     * @return
     */
    public List<ProvVO> selProvs(){
        MoProvExample example=new MoProvExample();
        return parseProv(moProvMapper.selectByExample(example));
    }

    /**
     * 转化省数据
     * @param provs
     * @return
     */
    private List<ProvVO> parseProv(List<MoProv> provs){
        return provs.stream().map(o -> {
            ProvVO p=new ProvVO();
            p.setName(o.getProvName());
            p.setProvId(o.getProvId());
            return p;
        }).collect(Collectors.toList());
    }

    /**
     * 查城市按省ID
     * @param provId
     * @return
     */
    public List<CityVO> selCityByProvId(Long userId,Long provId){
        MoCityExample example=new MoCityExample();
        example.createCriteria().andProvIdEqualTo(provId);
        return moCityMapper.selectByExample(example).stream().map(o -> {
            CityVO c=new CityVO();
            c.setCityId(o.getCityId());
            c.setName(o.getCityName());
            return c;
        }).collect(Collectors.toList());
    }

    /**
     * 按城市ID查区
     * @param cityId
     * @return
     */
    public List<AreaVO> selAreaByCityId(Long cityId){
        MoTownExample example=new MoTownExample();
        example.createCriteria().andCityIdEqualTo(cityId);
        return moTownMapper.selectByExample(example).stream().map(o -> {
            AreaVO vo=new AreaVO();
            vo.setName(o.getTownName());
            vo.setAreaId(o.getTownId().toString());
            return vo;
        }).collect(Collectors.toList());
    }

    /**
     * 查询用户是否经过实名认证
     * @param userId
     * @return
     */
    public Boolean hasRealBind(Long userId){
        return managerUserMapper.selectByPrimaryKey(userId).getHasRealName();
    }

    /**
     * 查询我的卡列表
     * @param userId
     * @return
     */
    public List<CreditCardVO> myCreditCards(Long userId){
        MoCardExample example=new MoCardExample();
        example.createCriteria().andUserIdEqualTo(userId);
        return moCardMapper.selectByExample(example).stream().map(o -> {
            CreditCardVO vo=new CreditCardVO();
            vo.setCardBankName(o.getBankName());
            vo.setCardIcon(o.getBankIcon());
            vo.setCardId(o.getCardId());
            vo.setCardNo(secretCardNum(o.getBankNo()));
            return vo;
        }).collect(Collectors.toList());
    }

    private String secretCardNum(String cardNum){
        if (StringUtils.isEmpty(cardNum)||cardNum.length()<8) {
            return cardNum;
        }
        return cardNum.substring(0,4)+" **** **** "+cardNum.substring(cardNum.length()-4,cardNum.length());
    }

    /**
     * 删除我的信用卡
     * @param ids
     */
    public void deleteCreditCards(Long userId,String ids){
        String[] idarr=ids.split(",");
        List<Long> cids=new ArrayList<>();
        for(String id:idarr){
            cids.add(Long.valueOf(id));
        }
        if (cids.size()==0) {
            return;
        }
        MoCardExample example=new MoCardExample();
        example.createCriteria().andUserIdEqualTo(userId).andCardIdIn(cids);
        moCardMapper.deleteByExample(example);
    }

    /**
     * 收款接口
     * @param userId 用户ID
     * @param creditCardId 信用卡ID
     * @param withdrawalMoney 金额
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public String receive(Long userId,Long creditCardId,Double withdrawalMoney,Long passageId) throws PassagewayException {
        MoPassagewayAccountExample accountExample=new MoPassagewayAccountExample();
        accountExample.createCriteria().andUserIdEqualTo(userId);
        MoPassagewayAccount account=new MoPassagewayAccount();
        account.setUsedStatus(false);
        moPassagewayAccountMapper.updateByExampleSelective(account,accountExample);
        accountExample.clear();
        accountExample.createCriteria().andUserIdEqualTo(userId).andPassagewayIdEqualTo(passageId);
        account.setUsedStatus(true);
        moPassagewayAccountMapper.updateByExampleSelective(account,accountExample);
        //查出开户信息和信用卡
        //查出信用卡银行卡
        return passagewayRoute.selwayByPid(passageId).toPay(userId,creditCardId,withdrawalMoney);
    }

    /**
     * 查询用户ID
     * @param telephone
     * @return
     */
    public Long selUserIdByUserName(String telephone) throws MoException {
        ManagerUserExample example=new ManagerUserExample();
        example.createCriteria().andLoginNameEqualTo(telephone);
        example.setStartIndex(0);
        example.setEndIndex(1);
        List<ManagerUser> users=managerUserMapper.selectByConditionList(example);
        if (users.size()==0) {
            throw new MoException("手机号对应的用户不存在");
        }
        return users.get(0).getUserId();
    }

    /**
     * 修改密码
     * @param userId
     * @param pwd
     */
    public void changePwd(Long userId,String pwd){
        ManagerUser user=new ManagerUser();
        user.setUserId(userId);
        user.setPassword(CustomCredentialsMatcher.encrypt(pwd));
        managerUserMapper.updateByPrimaryKeySelective(user);
    }

    /**
     * 统计交易记录
     * @param userId
     * @return
     */
    public TradeCountVO countMyTrade(Long userId){
        Calendar cal=Calendar.getInstance();
        cal.set(Calendar.HOUR_OF_DAY,0);
        cal.set(Calendar.MINUTE,0);
        cal.set(Calendar.SECOND,0);
        cal.set(Calendar.MILLISECOND,0);
        Double todayCount=moOrderMapper.sumMoneyByTime(userId,cal.getTime());
        cal.add(Calendar.MONTH,-1);
        Double monthCount=moOrderMapper.sumMoneyByTime(userId,cal.getTime());
        TradeCountVO vo=new TradeCountVO();
        vo.setMonthTradeMoney(MoneyUtil.formatMoney(monthCount==null?0:monthCount));
        vo.setTodayTradeMoney(MoneyUtil.formatMoney(todayCount==null?0:todayCount));
        return vo;
    }

    /**
     * 查询交易列表
     * @param userId
     * @return
     */
    public List<TradeDataVO> selTradeDatas(Long userId){
        MoOrderExample example=new MoOrderExample();
        example.createCriteria().andUserIdEqualTo(userId).andStatusGreaterThan(1);
        example.setStartIndex(0);
        example.setEndIndex(50);
        example.setOrderByClause("create_time desc");
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return moOrderMapper.selectByConditionList(example).stream().map(o -> {
            TradeDataVO vo=new TradeDataVO();
            vo.setCardBankName(o.getCreditBank());
            vo.setCardIcon(o.getCreditIcon());
            vo.setTradeMoney(MoneyUtil.formatMoney(Double.valueOf(o.getMoney())));
            vo.setTradeState(o.getStatus());
            vo.setTradeTime(sdf.format(o.getCreateTime()));
            return vo;
        }).collect(Collectors.toList());

    }

    /**
     * 支付成功去结算
     * @param payed
     */
    public synchronized void paySucceed(PayedCallbackBO payed) throws PassagewayException {
        //更新订单状态
        String requestId=payed.getRequestId().replace(OEM_FLAG+"order_","");
        Long orderId=Long.valueOf(requestId);
        MoOrder order=moOrderMapper.selectFieldsByPrimaryKey(orderId, FieldUtil.codeFields("order_id,credit_bank"));
        if (order == null) {
            logger.error(orderId+" 此订单不存在");
            return;
        }
        //选择路由
        passagewayRoute.selwayByPid(1L).payCallBack(orderId,Double.valueOf(payed.getAmount()),Double.valueOf(payed.getFee()),
                payed.getStatus());

    }

    public void tuiwx(){
        Map<String,WxTempleateBaseData> wxTempleateDataMap=new HashMap<>();
        wxTempleateDataMap.put("first",new WxTempleateBaseData("恭喜你，获得一笔分润佣金！"));
        wxTempleateDataMap.put("keyword1",new WxTempleateBaseData("0.01"));
        wxTempleateDataMap.put("keyword2",new WxTempleateBaseData("2017-01-01"));
        wxTempleateDataMap.put("remark",new WxTempleateBaseData(SecretUtil.secretName("陶孢的") +
                "消费了1000.22元"));
        //发给老赵一份

            wxTempleateDataMap.put("first",new WxTempleateBaseData("恭喜[9999]，获得一笔分润佣金！","#9E272A"));
            try {
                String token=wxTokenService.getSystemToken().getAccess_token();
                wxTokenService.sendTemplateMsg(PAYED_TEMPLATE,ADMIN_NOTIFY,wxTempleateDataMap,MAIN_HOST+"wappage/agpage/tradeDetail",token);
            } catch (Exception e) {
                logger.error("发消息失败",e);
            }

    }

    /**
     * 结算成功分润
     * 1、查出结算记录
     * 2、查出订单
     * 3、查出用户
     * 4、查出代理
     * 5、查出通道费率，目前暂时唯一
     * 6、利用费率着分润
     *
     * @param bo
     */
    public synchronized void settlementSucceed(SettlementCallbackBO bo) throws YeepayException{
        Long settlementId=Long.valueOf(bo.getExternalNo().replace(OEM_FLAG+"settlement_",""));
        MoSettlement settle=moSettlementMapper.selectByPrimaryKey(settlementId);
        if (settle == null||settle.getStatus()==2) {
            throw new YeepayException(bo.getExternalNo()+"_不存在或重复推");
        }
        //更新结算状态
        MoSettlement settlement=new MoSettlement();
        settlement.setSettlementId(settlementId);
        switch (bo.getTransferStatus()){
            case "RECEIVED":settlement.setStatus(3);break;
            case "PROCESSING":settlement.setStatus(4);break;
            case "SUCCESSED":settlement.setStatus(2);break;
            case "FAILED":settlement.setStatus(5);break;
            case "REFUNED":settlement.setStatus(6);break;
            case "CANCELLED":settlement.setStatus(7);break;
        }
        if (settlement.getStatus() != null) {
            moSettlementMapper.updateByPrimaryKeySelective(settlement);
        }
    }

    /**
     * 新用户加入通知代理
     * @param busId
     */
    public void businessAddShowAgent(Long busId){
        ManagerUser business=managerUserMapper.selectByPrimaryKey(busId);
        if (business.getAgentId()==1) {//顶级商户
            return;
        }
        //发送分润提醒，先查出代理openid如果 没有则不发
        MoWxuserinfoExample wxExample=new MoWxuserinfoExample();
        wxExample.createCriteria().andUserIdEqualTo(business.getAgentId());
        wxExample.setStartIndex(0);
        wxExample.setEndIndex(1);
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        List<MoWxuserinfo> wxinfos=moWxuserinfoMapper.selectByConditionList(wxExample);
        if (wxinfos.size()==0) {
            return;
        }
        Map<String,WxTempleateBaseData> wxTempleateDataMap=new HashMap<>();
        wxTempleateDataMap.put("first",new WxTempleateBaseData("恭喜你，成功拓展一个商户！"));
        wxTempleateDataMap.put("keyword1",new WxTempleateBaseData(business.getRealName()));
        wxTempleateDataMap.put("keyword2",new WxTempleateBaseData(sdf.format(new Date())));
        wxTempleateDataMap.put("remark",new WxTempleateBaseData(""));
        try {
            String token=wxTokenService.getSystemToken().getAccess_token();
            wxTokenService.sendTemplateMsg(NEW_COM,wxinfos.get(0).getOpenId(),wxTempleateDataMap,MAIN_HOST+"wappage/agpage/seeMerchant",token);
        } catch (Exception e) {
            logger.error("发消息失败",e);
        }
    }

    public List<BankLimitVO> selBankLimits(Long pid){
        MoBankLimitExample example=new MoBankLimitExample();
        example.createCriteria().andPassageIdEqualTo(pid);
        return BeanMapper.mapList(moBankLimitMapper.selectByExample(example),BankLimitVO.class);
    }

    /**
     * 按用户查询通道
     * @param userId
     * @return
     */
    public List<PassageWaysVO> selPassageWaysByUserId(Long userId,Long creditCardId){
        //先查出通道
        //查开户状态
        //查封顶
        MoPassagewayExample passagewayExample=new MoPassagewayExample();
        passagewayExample.createCriteria().andEnabledEqualTo(true);
        List<PassageWaysVO> vos = moPassagewayMapper.selectByExample(passagewayExample).stream().map(o -> {
            PassageWaysVO vo=new PassageWaysVO();
            vo.setName(o.getTitle());
            vo.setPid(o.getPassagewayId());
            vo.setTimeMin(o.getTimeMin());
            MoPassagewayAccountExample accountExample=new MoPassagewayAccountExample();
            accountExample.createCriteria().andUserIdEqualTo(userId).andPassagewayIdEqualTo(o.getPassagewayId());
            List<MoPassagewayAccount> accounts=moPassagewayAccountMapper.selectByExample(accountExample);
            if (accounts.size()==0) {//此通道没激活
                vo.setActiveStatus(1);
                vo.setRate(MoneyUtil.dealRate(o.getSysMax()));
                vo.setSettle(Double.valueOf(o.getCashMoney()).longValue()+"");
            }else {
                MoPassagewayAccount account=accounts.get(0);
                vo.setActiveStatus(account.getExamineStatus()==2?2:(account.getExamineStatus()==3?4:3));
                vo.setIsSelected(account.getUsedStatus()?2:1);
                vo.setRate(MoneyUtil.dealRate(account.getRate()));
                vo.setSettle(Double.valueOf(account.getCashMoney()).longValue()+"");
            }
                //查询一下限额情况
                MoBankLimit limit=moBankLimitMapper.selByCreditCardId(creditCardId,o.getPassagewayId());
                if (limit == null) {
                    vo.setMax("5万");
                    vo.setEnabled(2);
                    vo.setMaxInt("50000");
                }else{
                    String timeLimit=limit.getTimeLimit();
                    vo.setMaxInt(timeLimit);
                    Double limitDouble=Double.valueOf(timeLimit)/10000;
                    DecimalFormat df=new DecimalFormat("0.##");
                    vo.setMax(df.format(limitDouble)+"万");
                    vo.setEnabled(limit.getEnabled()?2:1);
                }
                //中付私人订制
            if (o.getPassagewayId()==2L&&vo.getEnabled()==2) {
                //交易时间7点到22点
                Calendar cal=Calendar.getInstance();
                int nowHour=cal.get(Calendar.HOUR_OF_DAY);
                boolean timeCan=nowHour>7&&nowHour<22;
                vo.setEnabled(timeCan?2:1);
                //今天刷卡额度超过49500，不给刷了
                if (timeCan) {
                    Date now=cal.getTime();
                    cal.set(Calendar.HOUR_OF_DAY,0);
                    Double total=moOrderMapper.sumPassageByTime(2L,cal.getTime(),now);
                    vo.setEnabled(total==null||total<49500d?2:1);
                }
            }else if(o.getPassagewayId()==3L&&vo.getEnabled()==2){
                Calendar cal=Calendar.getInstance();
                int nowHour=cal.get(Calendar.HOUR_OF_DAY);
                int minit=cal.get(Calendar.MINUTE);
                boolean timeCan=nowHour>7&&nowHour<22||nowHour==22&&minit<=30;
                vo.setEnabled(timeCan?2:1);
            }
           return vo;
        }).collect(Collectors.toList());
        //判定选中事项，提取第一个正常项，如果全部正常顶中无选中状态，拿第一个正常项为选中项
        PassageWaysVO firstV=null;
        boolean hasSel=false;
        for(PassageWaysVO v:vos){

            if (firstV == null&&v.getEnabled()==2) {
                firstV=v;
            }
            if (v.getEnabled()==2&&v.getIsSelected()==2) {
                hasSel=true;
            }else if(v.getEnabled()==1&&v.getIsSelected()==2){
                v.setIsSelected(1);
            }
        }
        if (!hasSel&&firstV!=null) {
            firstV.setIsSelected(2);
        }
        return vos;
    }

    /**
     * 查联行号并固化
     * @param bankName
     * @param bankNumber
     * @param location
     * @return
     */
    public String writeLinkNo(String bankName,String bankNumber,String location){
        return linknoUtil.writeLinkNo(bankName,bankNumber,location);
    }

    /**
     * 激活一个通道
     * @param pid
     */
    public void activePassway(Long userId,Long pid) throws PassagewayException {
        Passageway way=passagewayRoute.selwayByPid(pid);
        //查出第一个激活过的通道注册信息
        MoPassagewayAccount account=moPassagewayAccountMapper.selByUserId(userId,1L);
        RegistBO bo=new RegistBO();
        bo.setRealName(account.getRealName());
        bo.setIdCard(account.getBodyNumber());
        bo.setBankName(account.getBankName());
        bo.setBankLocation(account.getBankLocation());
        bo.setBankAccountNumber(account.getBankNumber());
        bo.setTelephone(account.getTelephone());
        bo.setAreaCode(account.getAreaCode());
        bo.setUserId(userId);
        if (pid.equals(3L)) {//联动的放上联行号
            bo.setLinkno(writeLinkNo(account.getBankName(),account.getBankNumber(),account.getBankLocation()));
            // TODO: 18/2/27 这个处理对陈龙不太好
            MoPassageway passageway=moPassagewayMapper.selectByPrimaryKey(pid);
            Double sysMax=Double.valueOf(passageway.getSysMax());
            Double calRate=Double.valueOf(account.getRate())-0.0002d;
            bo.setRate(calRate>sysMax?sysMax:calRate);
        }else if(pid.equals(2L)){
            // TODO: 18/2/27 这个处理对陈龙不太好 
            MoPassageway passageway=moPassagewayMapper.selectByPrimaryKey(pid);
            Double sysMax=Double.valueOf(passageway.getSysMax());
            Double calRate=Double.valueOf(account.getRate())-0.001d;
            bo.setRate(calRate>sysMax?sysMax:calRate);
        }
        way.regist(bo);

        if (pid.equals(3L)) {//有回调时间，给他停5秒
            try {
                Thread.sleep(5000L);
            } catch (InterruptedException e) {
            }
        }
    }

    /**
     * 中付付款成功回调
     */
    public synchronized void unPayCallback(ConsumptionResponse bo) throws PassagewayException {
        Double amount=Double.valueOf(bo.getTxnAmt());
        amount=MoneyUtil.formatMoneyDouble(amount/100);
        MoOrderExample example=new MoOrderExample();
        example.createCriteria().andOrderCodeEqualTo(bo.getOrderId());
        List<MoOrder> orders=moOrderMapper.selectByExample(example);
        if (orders.size()==0) {
            return;
        }
        MoOrder order=orders.get(0);
        //先把联行号做上
        MoPassagewayAccountExample accountExample=new MoPassagewayAccountExample();
        accountExample.createCriteria().andUserIdEqualTo(order.getUserId()).andPassagewayIdEqualTo(2L);
        MoPassagewayAccount account=moPassagewayAccountMapper.selectByExample(accountExample).get(0);
        linknoUtil.writeLinkNo(account.getBankName(),account.getBankNumber(),account.getBankLocation());
        Double fee=Double.valueOf(order.getRate())*Double.valueOf(order.getMoney());
        passagewayRoute.selwayByPid(2L).payCallBack(order.getOrderId(),amount,MoneyUtil.formatMoneyDouble(fee),
                bo.isSuccess()?"SUCCESS":"ERROR");
    }
    /**
     * 得到中付的交易数据
     * @param userId
     * @param oid
     * @return
     */
    public Map<String,String> unpayData(Long userId,Long oid) throws UnpayException {
        MoOrder order=moOrderMapper.selectByPrimaryKey(oid);
        if (order == null) {
            throw new UnpayException("交易不存在");
        }
        if (!order.getUserId().equals(userId)) {
            throw new UnpayException("只能支付本用户下的交易");
        }
        SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMddHHmmss");
        DecimalFormat df=new DecimalFormat("000000");
        String orderCode=sdf.format(new Date())+df.format(order.getOrderId());
        MoOrder o=new MoOrder();
        o.setOrderId(oid);
        o.setOrderCode(orderCode);
        moOrderMapper.updateByPrimaryKeySelective(o);
        //查出通道
        MoPassagewayAccountExample accountExample=new MoPassagewayAccountExample();
        accountExample.createCriteria().andUserIdEqualTo(userId).andPassagewayIdEqualTo(order.getPassagewayId());
        MoPassagewayAccount account=moPassagewayAccountMapper.selectByExample(accountExample).get(0);
        ConsumptionRequest req=new ConsumptionRequest();
        req.setOrderId(orderCode);
        Double money=Double.valueOf(order.getMoney())*100;
        req.setTxnAmt(money.longValue()+"");
//        req.setMerCatCode(order.getMcc());
        req.setSubMerId(account.getAccountCode());
        req.setIdName(account.getRealName());
        req.setAccNo(order.getCreditNo());
        req.setPhoneNo(order.getMobileName());
        req.setIdNo(account.getBodyNumber());
//        req.setFrontUrl(MAIN_HOST+"wappage/buspage/index");
        req.setFrontUrl(MAIN_HOST+"bus/unpayCallback.htm");
        req.setBackUrl(MAIN_HOST+"bus/unpayAsyncCallback.htm");
        Calendar cal=Calendar.getInstance();
        req.setTxnTime(sdf.format(cal.getTime()));
        cal.add(Calendar.DATE,1);
        req.setPayTimeout(sdf.format(cal.getTime()));
        req.setSettType("0");
        req.setTxMerCommisionValue(MoneyUtil.dealRate(account.getRate()).replace("%",""));
        try {
            return req.signedData();
        } catch (Exception e) {
            throw new UnpayException("参数组织失败");
        }
    }

}
